package main

import (
	"fmt"
	"sync"
	"sync/atomic"
)

func main() {
	var sum uint32 = 0
	var wg sync.WaitGroup
	for i := 0; i < 50000; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			//sum += 1                 //1.A  使用A方式，最后sum的值是不定的，取决于sum的同步情况
			atomic.AddUint32(&sum, 1) //1.B 使用B方式，由于sync/atomic 库提供了原子操作的支持，原子操作直接有底层CPU硬件支持，因而一般要比基于操作系统API的锁方式效率高些
			//2.C 使用C方式，没有B的效率高，先比较变量的值是否等于给定旧值，等于旧值的情况下才赋予新值，最后返回新值是否设置成功
			//if !atomic.CompareAndSwapUint32(&sum, sum, sum+1){
			//    fmt.Println("set value failed...")
			//}
			var res uint32
			res = atomic.LoadUint32(&sum)
			fmt.Println("res:", res, "sum:", sum)
		}()
	}
	wg.Wait()
	fmt.Println(sum)
}
